package com.ants.boot.core.security.provider;

import com.ants.boot.core.security.service.PhoneUserDetailsServiceImpl;
import com.ants.boot.core.security.token.PhoneAuthenticationToken;
import com.ants.boot.utils.PhoneCodeUtils;
import com.ants.boot.utils.RedisUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.BadCredentialsException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.stereotype.Component;
/**
 * @author 蚂蚁会花呗
 * @date 2022/10/9 9:25
 * 手机短信验证码认证器提供者
 */
@Component
public class PhoneAuthenticationProvider implements AuthenticationProvider {

    Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private PhoneUserDetailsServiceImpl phoneUserDetailsService;


    @Override
    public Authentication authenticate(Authentication authentication) throws AuthenticationException {
        logger.info("手机号验证码开始校验");
        String username = authentication.getName();
        String rawCode = authentication.getCredentials().toString();
        if (StringUtils.isBlank(username)){
            logger.error("手机号码不能为空！");
            throw new BadCredentialsException("手机号码不能为空！");
        }
        if (StringUtils.isBlank(rawCode)){
            logger.error("验证码不能为空！");
            throw new BadCredentialsException("验证码不能为空！");
        }
        Object redisCode = redisUtils.get(PhoneCodeUtils.codeStartWith(username));
        if (redisCode == null){
            logger.error("验证码失效，请重新获取！");
            throw new BadCredentialsException("验证码失效，请重新获取！");
        }
        UserDetails userDetails = phoneUserDetailsService.loadUserByUsername(username);
        if (redisCode.equals(rawCode)){
            logger.info("校验成功！");
            //校验成功后，删除缓存的数据
            redisUtils.delete(PhoneCodeUtils.codeStartWith(username));
            return new PhoneAuthenticationToken(userDetails, null,userDetails.getAuthorities());
        }else{
            throw new BadCredentialsException("验证码不正确，请重新获取！");
        }
    }

    @Override
    public boolean supports(Class<?> authentication) {
        boolean res = PhoneAuthenticationToken.class.isAssignableFrom(authentication);
        return res;
    }
}
